package com.seven.z7.logviewer.controls;

import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;

import com.seven.z7.logviewer.MainFrame;

/**
 * 
 * @author aprokofjev
 * 
 */
public class TextDropTarget implements DropTargetListener {

	private boolean mIsAcceptableType;
	private ActionListener mFrameActionListener;

	public TextDropTarget(Component c, ActionListener listener) {
		mFrameActionListener = listener;
		new DropTarget(c, DnDConstants.ACTION_COPY_OR_MOVE, this, true, null);
	}

	public void dragEnter(DropTargetDragEvent dtde) {
		mIsAcceptableType = dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor);

		acceptOrRejectDrag(dtde);
	}

	public void dragExit(DropTargetEvent dte) {
	}

	public void dragOver(DropTargetDragEvent dtde) {
		acceptOrRejectDrag(dtde);
	}

	public void dropActionChanged(DropTargetDragEvent dtde) {
		acceptOrRejectDrag(dtde);
	}

	public void drop(DropTargetDropEvent dtde) {
		if ((dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0) {

			dtde.acceptDrop(dtde.getDropAction());
			Transferable transferable = dtde.getTransferable();
			try {
				boolean result = dropFile(transferable);
				dtde.dropComplete(result);
				System.out.println("Drop completed, success: " + result);
			} catch (Exception e) {
				System.out.println("Exception while handling drop " + e);
				dtde.dropComplete(false);
			}
		} else {
			System.out.println("Drop target rejected drop");
			dtde.rejectDrop();
		}
	}

	private boolean acceptOrRejectDrag(DropTargetDragEvent dtde) {
		int dropAction = dtde.getDropAction();
		int sourceActions = dtde.getSourceActions();
		boolean acceptedDrag = false;

		// Reject if the object being transferred
		// or the operations available are not acceptable.
		if (!mIsAcceptableType || (sourceActions & DnDConstants.ACTION_COPY_OR_MOVE) == 0) {
			dtde.rejectDrag();
		} else if ((dropAction & DnDConstants.ACTION_COPY_OR_MOVE) == 0) {
			// Not offering copy or move - suggest a copy
			dtde.acceptDrag(DnDConstants.ACTION_COPY);
			acceptedDrag = true;
		} else {
			// Offering an acceptable operation: accept
			dtde.acceptDrag(dropAction);
			acceptedDrag = true;
		}

		return acceptedDrag;
	}

	// This method handles a drop for a list of files
	private boolean dropFile(Transferable transferable) throws IOException, UnsupportedFlavorException {
		Object o = transferable.getTransferData(DataFlavor.javaFileListFlavor);
		List<?> fileList = null;
		if (o instanceof List) {
			fileList = (List<?>) transferable.getTransferData(DataFlavor.javaFileListFlavor);
		} else {
			return false;
		}
		if (fileList == null || fileList.size() < 1) {
			return false;
		}

		ActionEvent ae = new ActionEvent(fileList, 0, MainFrame.ACTION_DROP);
		mFrameActionListener.actionPerformed(ae);
		return true;
	}
}
